import { Singleton } from 'decorates';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Handle = (args?: any) => void;

interface EventMap { [evt: string]: { [key: string]: Handle } }

/**
 * 全局事件服务
 */
@Singleton()
export default class EventService {
  /**
   * 事件字典
   */
  private eventMap: EventMap = {};
  /**
   * 公共事件
   */
  public static Events = {
    /**
     * 用户登陆
     */
    SIGNIN: 'signin',
    /**
     * 用户登陆
     */
    SIGNOUT: 'signout',
    /**
     * 设备数据更新
     */
    ITEMSYNC: 'item-sync',
    /**
     * 设备导航事件
     */
    LOOKAT: 'look-at',
    /**
     * 设备导航事件
     */
    QUICKLOCATE: 'quick-locate',
    /**
     * 地图位置改变回调
     */
    LOCATECHANGE: 'locate-change',
    /**
     * 全局每秒计时器
     */
    SECONDTIMER: 'second-timer',
    /**
     * 菜单栏隐藏/显示事件
     */
    HIDE_HEADER: 'hide-header'
  };

  /**
   * 监听某特定事件
   * @param evt 事件标志
   * @param handler 事件函数
   * @param unique 唯一键 用于事件互斥
   */
  public on (evt: string, handler: Handle, uniqueKey?: string) {
    if (!uniqueKey) {
      uniqueKey = Math.floor(Math.random() * 1000000) + '';
    }
    this.eventMap[evt] = this.eventMap[evt] || {};
    this.eventMap[evt][uniqueKey] = handler;
  }

  /**
   * 取消事件监听
   * @param evt 事件标志
   * @param handler 事件函数
   */
  public off (evt: string, handler: Handle) {
    if (!this.eventMap[evt]) {
      return false;
    }
    for (let key in this.eventMap[evt]) {
      if (this.eventMap[evt][key] === handler) {
        delete this.eventMap[evt][key];
        return true;
      }
    }
    return false;
  }

  /**
   * 触发某事件
   * @param evt 事件标志
   * @param args 事件参数
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  public emit (evt: string, args: any) {
    if (!this.eventMap[evt]) {
      return;
    }
    for (let key in this.eventMap[evt]) {
      try {
        this.eventMap[evt][key](args);
      } catch (e) {
        //
      }
    }
  }
}
